<!--
 * @Author: yuanming
 * @Date: 2024-06-30 08:01:12
 * @LastEditors: yuanming
 * @LastEditTime: 2024-10-09 17:50:09
 * @Description: fileDescription
-->
<template>
    <div class="container">
        <div class="leftImgBg" />
        <div class="rightImgBg" />
        <template v-if="menuIndex !== 0">
            <div class="leftBg" />
            <div class="rightBg" />
        </template>
        <img src="@/assets/images/borderTop.png" class="borderTopImg">
        <img src="@/assets/images/borderBottom.png" class="borderBottomImg">
        <HeaderTitle />
        <MenuComponent :current="menuIndex" @change="changeMenu" />
        <template v-if="menuIndex === 0">
            <Transition name="fade" mode="out-in" appear>
                <DataMonitor :filingPark="filingPark" :sharedBicycles="sharedBicycles" />
            </Transition>
        </template>
        <template v-if="[1, 2].includes(menuIndex) && viewType === '1'">
            <transition name="fade" mode="out-in" appear>
                <component :is="menuIndex === 1 ? ParkMonitorLeft : bikeMonitorLeft" :filingPark="filingPark"></component>
            </transition>
            <transition name="fade" mode="out-in" appear>
                <component :is="menuIndex === 1 ? ParkMonitorRight : bikeMonitorRight" :filingParkInfo="filingParkInfo"></component>
            </transition>
        </template>
        <template v-if="[1, 2].includes(menuIndex)">
            <div id="map" />
            <div class="radioWarp">
                <el-radio-group v-model="viewType" @change="changeViewType">
                    <template v-if="menuIndex === 1">
                        <el-radio value="1">默认视图</el-radio>
                        <el-radio value="2">停车资源分布热力图</el-radio>
                        <el-radio value="3">停车泊位占用热力图</el-radio>
                    </template>
                    <template v-if="menuIndex === 2">
                        <el-radio value="1">默认视图</el-radio>
                        <el-radio value="2">共享单车分布热力图</el-radio>
                        <el-radio value="3">非机动车泊位分布</el-radio>
                    </template>
                </el-radio-group>
            </div>
        </template>

        <InfoWindow v-show="showInfoWindow" ref="infoWindowDom" :current-index="menuIndex" :visible="showInfoWindow" :info="clickInfo" @clickMap="clickMap" />
    </div>
</template>
<script setup>
import { ElMessage } from 'element-plus'
import { ref } from 'vue'
import HeaderTitle from '@/components/title/index.vue'
import MenuComponent from '@/components/menu/index.vue'
import DataMonitor from '@/components/dataMonitor/index.vue'
import ParkMonitorLeft from '@/components/parkMonitor/left.vue'
import ParkMonitorRight from '@/components/parkMonitor/right.vue'
import bikeMonitorLeft from '@/components/bikeMonitor/left.vue'
import bikeMonitorRight from '@/components/bikeMonitor/right.vue'

import InfoWindow from '@/components/infoWindow/index.vue'

import YH from '@/assets/json/yh.json'
import SHQ from '@/assets/json/shq.json'
import XSQ from '@/assets/json/xsq.json'
import BQ from '@/assets/json/bq.json'
import TXQ from '@/assets/json/txq.json'
import MS from '@/assets/json/ms2.json'
import YHJJKFQ from '@/assets/json/yhjjkfq.json'
import BQXC from '@/assets/json/bqxc.json'

import { nowSize } from '@/utils/index'

const { proxy } = getCurrentInstance()

const menuIndex = ref(0)

const viewType = ref('1')

const map = ref(null)

const loca = ref(null)

const heatmap = ref(null)

const showInfoWindow = ref(false)

const clickInfo = ref({})

const infoWindow = ref(null)

const parkList = ref([])

const bikeList = ref([])

const cluster = ref(null)

const streetData = ref([
    { json: YH, data: { custId: '8010000123436', color: '#f53bc9', name: '雨花街道', value: [118.775667, 31.991852] } },
    { json: SHQ, data: { custId: '8010000123437', color: '#26b9e6', name: '赛虹桥街道', value: [118.764648, 32.014316] } },
    { json: XSQ, data: { custId: '8010000123440', color: '#2279be', name: '西善桥街道', value: [118.71625, 31.95854] } },
    { json: TXQ, data: { custId: '8010000123439', color: '#1bb47e', name: '铁心桥街道', value: [118.744062, 31.935897] } },
    { json: BQ, data: { custId: '8010000123441', color: '#e9721a', name: '板桥街道', value: [118.658341, 31.922518] } },
    { json: MS, data: { custId: '8010000123443', color: '#22d9ff', name: '梅山街道', value: [118.631532, 31.901024] } },
    { json: YHJJKFQ, data: { custId: '8010000123442', color: '#b0f21c', name: '雨花经济开发区', value: [118.654619, 31.928271] } },
    { json: BQXC, data: { custId: '8010000123444', color: '#47aaff', name: '古雄街道', value: [118.666707, 31.91186] } },
])

const filingPark = ref({})
const sharedBicycles = ref({})
const filingParkInfo = ref({})

const setClusterInMap = (markers, gridSize = 55) => {
    if (cluster.value) {
        cluster.value.setMap(null)
    }
    const count = markers.length
    const renderClusterMarker = (context) => {
        const factor = (context.count / count) ** (1 / 18)
        const Hue = 180 - factor * 180
        const bgColor = `hsla(${Hue},100%,40%,0.7)`
        const fontColor = `hsla(${Hue},100%,90%,1)`
        const borderColor = `hsla(${Hue},100%,40%,1)`
        const shadowColor = `hsla(${Hue},100%,90%,1)`

        const div = document.createElement('div')
        div.style.backgroundColor = bgColor
        const size = Math.round(18 + (context.count / count) ** (1 / 5) * 20)
        div.style.width = `${size}px`
        div.style.height = `${size}px`
        div.style.borderRadius = `${size / 2}px`
        div.innerHTML = context.count
        div.style.lineHeight = `${size}px`
        div.style.color = fontColor
        div.style.border = `solid 1px ${borderColor}`
        div.style.borderRadius = `${size / 2}px`
        div.style.boxShadow = `0 0 5px ${shadowColor}`
        div.style.fontSize = `${nowSize(12)}px`
        div.style.textAlign = 'center'
        context.marker.setContent(div)
    }
    const renderMarker = (context) => {
        let content = '<div class=\'markerBox\'></div>'
        if (context.data[0].channel === 2) {
            content = '<div class=\'markerBox1\'></div>'
        } else if (context.data[0].channel === 3) {
            content = '<div class=\'markerBox2\'></div>'
        }
        context.marker.setContent(content)
        context.marker.setAnchor('bottom-center')
    }
    cluster.value = new AMap.MarkerCluster(map.value, markers, {
        gridSize, // 设置网格像素大小
        renderClusterMarker, // 自定义聚合点样式
        renderMarker, // 自
    })
}

/**
 * 添加热力图
 * @param {*} list 数据源
 */
function setHeatMap(list) {
    const type = viewType.value === '2' ? 'park' : 'seat'
    const features = []
    list.map((item) => {
        const seatRate = item.capacityNum ? (item.freeNum / item.capacityNum).toFixed(4) * 1 : 0
        const obj = {
            type: 'Feature',
            properties: {
                count: menuIndex.value === 1 && type === 'seat' ? seatRate : 1,
            },
            geometry: {
                type: 'Point',
                coordinates: [item.lng * 1, item.lat * 1],
            },
        }
        features.push(obj)
    })

    heatmap.value = new Loca.HeatMapLayer({
        loca: loca.value,
        zIndex: 10,
        opacity: 1,
        visible: true,
        zooms: [2, 22],
    })

    const heatmapSource = new Loca.GeoJSONSource({
        data: {
            type: 'FeatureCollection',
            features,
        },
    })

    heatmap.value.setSource(heatmapSource)
    heatmap.value.setStyle({
        unit: 'px',
        radius: menuIndex.value === 2 && type === 'park' ? 5 : 25,
        value: (index, feature) => feature.properties.count,
        gradient: {
            1: '#FF4C2F',
            0.2: '#29CF6F',
            0.4: '#5CE182',
            0.5: '#7DF675',
            0.6: '#FFF100',
            0.8: '#FAA53F',
        },
        min: 0,
        max: 1,
    })

    // list.map((item) => {
    //     const obj = {
    //         lng: item.lng * 1,
    //         lat: item.lat * 1,
    //     }
    //     if (menuIndex.value === 1) {
    //         obj.count = type === 'park' ? 10 : item.seatNum
    //     } else {
    //         obj.count = 10
    //     }
    //     data.push(obj)
    // })
    // map.value.plugin(['AMap.HeatMap'], () => {
    //     heatmap.value = new AMap.HeatMap(map.value, {
    //         radius: 25, // 热力图的半径
    //         opacity: [0, 0.8],
    //         gradient: {
    //             0.5: 'blue',
    //             0.65: 'rgb(117,211,248)',
    //             0.7: 'rgb(0, 255, 0)',
    //             0.9: '#ffea00',
    //             1.0: 'red',
    //         },
    //     })
    //     heatmap.value.setDataSet({ data })
    // })
}

const clickMap = () => {
    if (infoWindow.value) {
        infoWindow.value.close()
        infoWindow.value = null
        showInfoWindow.value = false
    }
}

/**
 * 清楚地图上的覆盖物
 */
function clearMap() {
    map.value && map.value.clearMap()
    if (loca.value) {
        loca.value.clear()
    }
    if (cluster.value) {
        cluster.value.setMap(null)
    }
    cluster.value = null
    clickMap()
    clickInfo.value = {}
}

/**
 * 设置飞线
 */
function setLineInMap(list) {
    const features = []
    list.map((item) => {
        const obj = {
            type: 'Feature',
            properties: {
                type: item.lineState,
            },
            geometry: {
                type: 'LineString',
                coordinates: [[item.lng * 1, item.lat * 1], [118.776914, 32.003146]],
            },
        }
        features.push(obj)
    })

    const inLineSource = new Loca.GeoJSONSource({
        data: {
            type: 'FeatureCollection',
            features,
        },
    })

    const inLinelayer = new Loca.PulseLineLayer({
        loca: loca.value,
        zIndex: 11,
        opacity: 1,
        visible: true,
        zooms: [2, 22],
    })

    inLinelayer.setStyle({
        altitude: 0,
        lineWidth: 2,
        headColor: (_, feature) => (feature.properties.type === 1 ? '#74DAD5' : '#FDDA7D'),
        interval: 2,
        duration: 2000,
    })
    inLinelayer.setSource(inLineSource)
}

/**
 * 设置默认点位
 */
function setMarkerInMap() {
    const marker = new AMap.Marker({
        position: new AMap.LngLat(118.776914, 32.003146),
        anchor: 'center',
        icon: new AMap.Icon({
            size: new AMap.Size(100, 100),
            image: new URL('@/assets/images/icon34.png', import.meta.url).href,
            imageSize: new AMap.Size(100, 100),
        }),
        zIndex: 5000,
    })
    map.value.add(marker)
}

/**
 * 设置呼吸点
 * @param {*} list 需要渲染的数组
 * @param {*} type 停车场类型 1 在线 2 离线
 */
function setScatterInMap(list, type) {
    const features = []
    const markerList = []

    const markerImages = type === 1 ? new URL('@/assets/images/icon35.png', import.meta.url).href : new URL('@/assets/images/icon36.png', import.meta.url).href
    const scatterImages = type === 1 ? new URL('@/assets/images/breath_blue.png', import.meta.url).href : new URL('@/assets/images/breath_red.png', import.meta.url).href

    list.map((item) => {
        const obj = {
            type: 'Feature',
            geometry: {
                type: 'Point',
                coordinates: [item.lng * 1, item.lat * 1],
            },
        }
        features.push(obj)
        const marker = new AMap.Marker({
            map: map.value,
            position: new AMap.LngLat(item.lng * 1, item.lat * 1),
            anchor: 'bottom-center',
            content: `<img class='mapMarker' src="${markerImages}">`,
            zIndex: 20,
        })
        marker.on('click', () => {
            clickInfo.value = item
            showInfoWindow.value = true
            infoWindow.value = new AMap.InfoWindow({
                isCustom: true, // 使用自定义窗体
                content: proxy.$refs.infoWindowDom.$el,
                anchor: 'center',
            })
            infoWindow.value.open(map.value, [item.lng * 1, item.lat * 1])
            map.value.setCenter([item.lng * 1, item.lat * 1], true)
        })
        // const numMarker = new AMap.Marker({
        //     map: map.value,
        //     position: new AMap.LngLat(item.position[0], item.position[1]),
        //     anchor: 'bottom-center',
        //     content: '<div class=\'numMapMarker\'>8</div>',
        // })
        // markerList.push([marker, numMarker])
        markerList.push([marker])
    })

    const scatter = new Loca.ScatterLayer({
        loca: loca.value,
        zIndex: 113,
        opacity: 1,
        visible: true,
        zooms: [2, 22],
    })
    const scatterGeo = new Loca.GeoJSONSource({
        data: {
            type: 'FeatureCollection',
            features,
        },
    })
    scatter.setSource(scatterGeo)
    scatter.setStyle({
        unit: 'px',
        size: [30, 30],
        borderWidth: 0,
        texture: scatterImages,
        duration: 500,
        animate: true,
    })
}

/**
 * 渲染点位
 */
function renderScatter() {
    const onlineList = parkList.value.filter((item) => item.lineState === 1)
    const offlineList = parkList.value.filter((item) => item.lineState === 0)

    setScatterInMap(onlineList, 1)
    setScatterInMap(offlineList, 2)

    setLineInMap(onlineList)
}

const getStreetBikeTrend = (req, info) => {
    const point = new AMap.LngLat(info.lngAndLatList[0].lng, info.lngAndLatList[0].lat)
    proxy.$api.getParkBikeTrend(req).then((res) => {
        const {
            hBike, mBike, qBike, toatalBike, totalShareBikNum,
        } = res
        const xData = toatalBike && toatalBike.length > 0 ? toatalBike.map((item) => `${item.time}时`) : [...new Array(7).keys()]
        clickInfo.value = {
            ...info,
            totalShareBikNum,
            lineAreaData: {
                xData,
                sData: [
                    { name: '总量数', value: toatalBike.map((item) => item.carNum * 1), color: '#65EAA2' },
                    { name: '美团', value: mBike.map((item) => item.carNum * 1), color: '#FEA50B' },
                    { name: '青桔', value: qBike.map((item) => item.carNum * 1), color: '#98FFF5' },
                    { name: '哈罗', value: hBike.map((item) => item.carNum * 1), color: '#30BBFF' },
                ],
                xColor: '#CDE4FF',
                yColor: '#CDE4FF',
                legendShow: false,
                grid: {
                    left: '0%',
                    top: '5%',
                    right: '5%',
                    bottom: '0%',
                    containLabel: true,
                },
            },
        }
        showInfoWindow.value = true
        infoWindow.value = new AMap.InfoWindow({
            isCustom: true, // 使用自定义窗体
            content: proxy.$refs.infoWindowDom.$el,
            anchor: 'center',
        })
        infoWindow.value.open(map.value, point)
        map.value.setCenter(point, true)
    })
}

/**
 * 渲染街道信息
 * @param {*} parkPath
 */
const queryPolyline = (parkPath) => {
    const polylineList = []
    parkPath.map((item, index) => {
        if (item.type === 3) {
            const marker = new AMap.Marker({
                position: new AMap.LngLat(item.lngAndLatList[0].lng, item.lngAndLatList[0].lat),
                content: `<div class='bikeMarkerBox'><div class='roadTitle'>${item.roadName}</div></div>`,
                anchor: 'center',
                zIndex: 1000,
            })
            map.value.add(marker)
            marker.on('click', () => {
                const req = {
                    lng: item.lngAndLatList[0].lng, // 经度
                    lat: item.lngAndLatList[0].lat, // 纬度
                    scope: 2000, // 距离
                    timeType: 1,
                    id: item.id,
                }
                getStreetBikeTrend(req, item)
            })
        } else if (item.type === 2) {
            let colors = '#80fd60'
            const capacity = item.capacity * 1 || 0
            if (capacity <= 300 && capacity > 0) { // 绿色
                colors = '#80fd60'
            } else if (capacity <= 600 && capacity > 300) { // 黄色
                colors = '#622dec'
            } else { // 红色
                colors = '#f82425'
            }
            const path = []
            item.lngAndLatList.map((keys) => {
                path.push([keys.lng, keys.lat])
            })
            const pLine = new AMap.Polyline({
                path,
                strokeColor: colors,
                strokeWeight: 4,
                strokeOpacity: 1,
                zIndex: index + 1,
                cursor: 'pointer',
                lineJoin: 'round',
                lineCap: 'round',
                isOutline: true,
                outlineColor: '#ffffff',
                borderWeight: 2,
                extData: {
                    type: 'shareLine',
                },
            })
            polylineList.push(pLine)
            pLine.on('click', (e) => {
                clickInfo.value = item
                showInfoWindow.value = true
                infoWindow.value = new AMap.InfoWindow({
                    isCustom: true, // 使用自定义窗体
                    content: proxy.$refs.infoWindowDom.$el,
                    anchor: 'center'
                })
                infoWindow.value.open(map.value, [e.lnglat.lng, e.lnglat.lat])
                map.value.setCenter([e.lnglat.lng, e.lnglat.lat], true)
            })
        }
    })
    const overlayGroup = new AMap.OverlayGroup(polylineList)
    map.value.add(overlayGroup)
}

const getBikeData = () => {
    const req = {
        radius: '',
        regionCode: 320114,
        lng: '118.779087',
        lat: '31.991291',
    }
    proxy.$api.nearbyBike(req).then((res) => {
        if (res) {
            bikeList.value = res.shareBikeLocationDtos.map((item) => ({
                ...item,
                lnglat: [+item.lng, +item.lat],
            }))
            setClusterInMap(bikeList.value)
        }
    })
}

const getStreetDataInfo = () => {
    proxy.$api.getBikeConfigList().then((res) => {
        if (res) {
            queryPolyline(res)
        }
    })
}

const drawPolygon = (data, info) => {
    const polygon = new AMap.Polygon({
        path: data.features[0].geometry.coordinates,
        fillColor: info.color,
        strokeOpacity: 1,
        fillOpacity: 0.15,
        zIndex: 0,
        height: 5,
        strokeColor: info.color,
        strokeWeight: 3,
        strokeStyle: 'solid',
        strokeDasharray: [5, 5],
        extData: {
            name: info.name,
            type: 'streetPolygon'
        }
    })
    polygon.on('mouseover', () => {
        polygon.setOptions({
            fillOpacity: 0.4,
        })
    })
    polygon.on('mouseout', () => {
        polygon.setOptions({
            fillOpacity: 0.15,
            fillColor: info.color
        })
    })
    polygon.on('click', () => {
        clickMap()
    })
    map.value.add(polygon)
}

const setMapData = () => {
    streetData.value.map((item) => {
        drawPolygon(item.json, item.data)
    })
}

function changeViewType(e) {
    viewType.value = e
    clearMap()
    if (e === '1') {
        if (heatmap.value) {
            heatmap.value.hide()
        }
        heatmap.value = null
        if (menuIndex.value === 1) {
            setMarkerInMap()
            renderScatter()
        } else {
            setMapData()
            getBikeData()
        }
    } else if (e === '2') {
        map.value.setPitch(0)
        const list = menuIndex.value === 1 ? parkList.value : bikeList.value
        setHeatMap(list)
    } else if (e === '3') {
        map.value.setPitch(0)
        if (menuIndex.value === 1) {
            setHeatMap(parkList.value)
        } else {
            getStreetDataInfo()
        }
    }
}

/*
 * 初始化地图
 */
function initMap() {
    const buildingLayer = new AMap.Buildings({
        heightFactor: 1,
        wallColor: '#315393',
        roofColor: '#64BCED',
    })
    map.value = new AMap.Map('map', {
        // center: [118.755716, 31.958922],
        center: [118.776914, 32.003146],
        mapStyle: 'amap://styles/darkblue',
        zoom: 13,
        // pitch: 48,
        // viewMode: '3D',
        layers: [
            AMap.createDefaultLayer(),
            buildingLayer,
        ],
    })

    loca.value = new Loca.Container({
        map: map.value,
    })

    map.value.on('click', () => {
        clickMap()
    })
}

/**
 * 渲染地图上的视图
 */
const renderMapView = () => {
    if (menuIndex.value === 1) {
        setMarkerInMap()
        renderScatter()
        loca.value.animate.start()
    } else if (menuIndex.value === 2) {
        getBikeData()
    }
}

async function changeMenu(index) {
    if (index === menuIndex.value) return
    menuIndex.value = index
    viewType.value = '1'
    clearMap()
    if (index !== 0) {
        await nextTick() // 确保DOM已经渲染完成
        initMap()
        if (index === 2) {
            // map.value.setPitch(48) // 设置地图的俯仰角
            map.value.setCenter([118.693710, 31.937945]) // 设置地图的俯仰角
            setMapData()
        }
        renderMapView()
    } else {
        map.value = null
    }
}

function handleData(info) {
    const { filingParkResponse, sharedBicyclesResponse, filingParkInfoResponse, berthOccupyResponse } = info
    filingPark.value = {
        ...filingParkResponse,
        totalBikeNum: sharedBicyclesResponse.totalNum || 0,
        meiTuan: sharedBicyclesResponse.meiTuan || 0,
        qingJu: sharedBicyclesResponse.qingJu || 0,
        haLuo: sharedBicyclesResponse.haLuo || 0,
        berthOccupyResponse,
    }
    sharedBicycles.value = sharedBicyclesResponse

    filingParkInfo.value = filingParkInfoResponse

    parkList.value = filingParkInfoResponse.filingParkInfoDetail || []
}

const sendSocket = () => {
    const id = Math.floor(Math.random() * 900) + 100
    const ws = new WebSocket(`wss://yhparking.njyh.gov.cn/bigdata/websocket/${id}`)
    ws.onopen = () => {
        ElMessage({
            message: '数据接收成功',
            type: 'success',
        })
    }
    ws.onerror = () => {
        ElMessage({
            message: '数据接收失败',
            type: 'error',
        })
    }
    ws.onmessage = (e) => {
        const message = JSON.parse(e.data)
        if (message) {
            handleData(message)
        }
    }
}

const getDataFunction = () => {
    Promise.allSettled([proxy.$api.getFilingPark(), proxy.$api.getSharedBicycles(), proxy.$api.getFilingParkInfo(), proxy.$api.getBerthOccupy()]).then((res) => {
        const filingParkResponse = res[0].status === 'fulfilled' ? res[0].value : {}
        const sharedBicyclesResponse = res[1].status === 'fulfilled' ? res[1].value : {}
        const filingParkInfoResponse = res[2].status === 'fulfilled' ? res[2].value : {}
        const berthOccupyResponse = res[3].status === 'fulfilled' ? res[3].value : {}

        handleData({ filingParkResponse, sharedBicyclesResponse, filingParkInfoResponse, berthOccupyResponse })
        sendSocket()
    })
}

onBeforeMount(() => {
    getDataFunction()
})
</script>

<style lang="scss">
.el-radio-group {
    flex-direction: column;
    align-items: flex-start;
    flex-wrap: nowrap;
}
.el-radio-group .el-radio .el-radio__label {
    color: #a2ddff;
}
.el-radio-group .el-radio .el-radio__label {
    color: #a2ddff;
}
.el-radio__input.is-checked + .el-radio__label {
    color: white;
}
#map {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    z-index: 5;
}
.mapMarker {
    width: 50px;
    height: 30px;
    animation: moveY 2s infinite linear;
}
.numMapMarker {
    width: 35px;
    height: 35px;
    background: radial-gradient(circle, #ffffff 0%, #a2ffd4 100%);
    border-radius: 50%;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 20px;
    font-weight: bold;
    color: #ff9900;
    margin-bottom: 60px;
    animation: ballAnimation 4s linear;
}
@keyframes ballAnimation {
    0% {
        transform: translateY(0);
    }
    100% {
        transform: translateY(-8vh);
        opacity: 0;
    }
}
.bikeMarkerBox {
    width: 100px;
    height: 100px;
    background-size: 100% 100%;
    background-image: url("@/assets/images/icon40.png");
    .roadTitle {
        width: 100%;
        height: 25px;
        line-height: 25px;
        text-align: center;
        font-size: 12px;
    }
}
%commonMarkerIconStyle {
    width: 40px;
    height: 85px;
    background-size: 100% 100%;
}
.markerBox {
    @extend %commonMarkerIconStyle;
    background-image: url("@/assets/images/icon37.png");
}
.markerBox1 {
    @extend %commonMarkerIconStyle;
    background-image: url("@/assets/images/icon39.png");
}
.markerBox2 {
    @extend %commonMarkerIconStyle;
    background-image: url("@/assets/images/icon38.png");
}
@keyframes moveY {
    0% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-1vh);
    }
    100% {
        transform: translateY(0);
    }
}

.radioWarp {
    width: fit-content;
    height: auto;
    position: absolute;
    bottom: 6vh;
    right: 25vw;
    z-index: 100;
    padding: 2vh 1vw;
    box-sizing: border-box;
    background-image: url("@/assets/images/radioBg.png");
    background-size: 100% 100%;
    background-repeat: no-repeat;
}

%commonImgStyle {
    width: 100%;
    height: auto;
    position: absolute;
    z-index: 15;
    left: 0;
}
.borderTopImg {
    @extend %commonImgStyle;
    top: 0;
}
.borderBottomImg {
    @extend %commonImgStyle;
    bottom: 0;
}
%commonBgStyle {
    width: 26vw;
    height: 100%;
    position: absolute;
    top: 0;
    z-index: 10;
    background-size: auto 100%;
    background-repeat: no-repeat;
}
.leftBg {
    @extend %commonBgStyle;
    left: 0;
    background: linear-gradient(
        to left,
        rgba(36, 46, 56, 0.2) 0%,
        rgba(18, 51, 93, 0.97) 97%
    );
}
.rightBg {
    @extend %commonBgStyle;
    right: 0;
    background: linear-gradient(
        to right,
        rgba(36, 46, 56, 0.1) 1%,
        rgba(18, 51, 93, 0.97) 100%
    );
}
.leftImgBg {
    @extend %commonBgStyle;
    left: 0;
    background-image: url("@/assets/images/borderImg.png");
}
.rightImgBg {
    @extend %commonBgStyle;
    right: 0;
    background-image: url("@/assets/images/borderImg.png");
    transform: rotateY(180deg);
}
.container {
    width: 100vw;
    height: 100vh;
    overflow: hidden;
    background-image: url("@/assets/images/bg.png");
    background-size: 100% 100%;
    background-position: center;
    background-repeat: no-repeat;
    color: white;
    position: relative;
}
// 滚动条
::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

::-webkit-scrollbar-thumb {
    border-radius: 10px;
    background-color: rgba(200, 200, 200, 0.5);
    border: 2px solid transparent;
    background-clip: padding-box;
}

::-webkit-scrollbar-thumb:hover {
    background-color: rgba(200, 200, 200, 0.8);
}
.title-screen {
    width: 85%;
    height: auto;
    background-image: url("@/assets/images/icon10.png");
    background-size: contain;
    background-position: center;
    background-repeat: no-repeat;
    font-size: 1.2vw;
    font-family: "YouSheBiaoTiHei";
    color: #ffffff;
    padding: 1vh 1vw;
    box-sizing: border-box;
}
</style>
